<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Indexes on Expressions</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REV="MADE"
HREF="mailto:pgsql-docs@postgresql.org"><LINK
REL="HOME"
TITLE="PostgreSQL 9.1.2 Documentation"
HREF="index.html"><LINK
REL="UP"
TITLE="Indexes"
HREF="indexes.html"><LINK
REL="PREVIOUS"
TITLE="Unique Indexes"
HREF="indexes-unique.html"><LINK
REL="NEXT"
TITLE="Partial Indexes"
HREF="indexes-partial.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"><META
HTTP-EQUIV="Content-Type"
CONTENT="text/html; charset=ISO-8859-1"><META
NAME="creation"
CONTENT="2011-12-01T22:07:59"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="5"
ALIGN="center"
VALIGN="bottom"
><A
HREF="index.html"
>PostgreSQL 9.1.2 Documentation</A
></TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
TITLE="Unique Indexes"
HREF="indexes-unique.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
HREF="indexes.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="60%"
ALIGN="center"
VALIGN="bottom"
>Chapter 11. Indexes</TD
><TD
WIDTH="20%"
ALIGN="right"
VALIGN="top"
><A
TITLE="Partial Indexes"
HREF="indexes-partial.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="INDEXES-EXPRESSIONAL"
>11.7. Indexes on Expressions</A
></H1
><P
>   An index column need not be just a column of the underlying table,
   but can be a function or scalar expression computed from one or
   more columns of the table.  This feature is useful to obtain fast
   access to tables based on the results of computations.
  </P
><P
>   For example, a common way to do case-insensitive comparisons is to
   use the <CODE
CLASS="FUNCTION"
>lower</CODE
> function:
</P><PRE
CLASS="PROGRAMLISTING"
>SELECT * FROM test1 WHERE lower(col1) = 'value';</PRE
><P>
   This query can use an index if one has been
   defined on the result of the <TT
CLASS="LITERAL"
>lower(col1)</TT
>
   function:
</P><PRE
CLASS="PROGRAMLISTING"
>CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));</PRE
><P>
  </P
><P
>   If we were to declare this index <TT
CLASS="LITERAL"
>UNIQUE</TT
>, it would prevent
   creation of rows whose <TT
CLASS="LITERAL"
>col1</TT
> values differ only in case,
   as well as rows whose <TT
CLASS="LITERAL"
>col1</TT
> values are actually identical.
   Thus, indexes on expressions can be used to enforce constraints that
   are not definable as simple unique constraints.
  </P
><P
>   As another example, if one often does queries like:
</P><PRE
CLASS="PROGRAMLISTING"
>SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';</PRE
><P>
   then it might be worth creating an index like this:
</P><PRE
CLASS="PROGRAMLISTING"
>CREATE INDEX people_names ON people ((first_name || ' ' || last_name));</PRE
><P>
  </P
><P
>   The syntax of the <TT
CLASS="COMMAND"
>CREATE INDEX</TT
> command normally requires
   writing parentheses around index expressions, as shown in the second
   example.  The parentheses can be omitted when the expression is just
   a function call, as in the first example.
  </P
><P
>   Index expressions are relatively expensive to maintain, because the
   derived expression(s) must be computed for each row upon insertion
   and whenever it is updated.  However, the index expressions are
   <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>not</I
></SPAN
> recomputed during an indexed search, since they are
   already stored in the index.  In both examples above, the system
   sees the query as just <TT
CLASS="LITERAL"
>WHERE indexedcolumn = 'constant'</TT
>
   and so the speed of the search is equivalent to any other simple index
   query.  Thus, indexes on expressions are useful when retrieval speed
   is more important than insertion and update speed.
  </P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="indexes-unique.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="indexes-partial.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Unique Indexes</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="indexes.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Partial Indexes</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>